﻿'  ******************************************
'  **        PARTIAL ENGINE CLASS          **
'  ******************************************
'  ** Protocol X 1.0.2.0 D/R Impl.         **
'  **   Compiled to /Engine.vb             **
'  **   By Razorback                       **
'  ******************************************

Partial Public Class Engine

    Private _X1020_ObfuscationSeed As String
    Private _MFT_ENCRYPTION_SALT() As Byte = {&HC9, &H65, &H42, &H2B, &H99, &HDC, &H81, &HDA, &H26, &HBC, &H19, &H8A, &H9C, &HEE, &H68, &H8} ' Randomnly Generated  DONT CHANGE NEVER ' SYNC WITH COMPILER
    Private Function _Mount_X1020(ByVal filename As String, ByRef signature() As Byte, ByRef certCode() As Byte, ByRef reservedArea1() As Byte, ByRef protocolVersion() As Byte, ByVal hookSequence As MountSequence, ByRef data() As Byte, ByRef data2() As String, ByRef data3 As ULong) As Boolean
        ' INHERITS FROM X1010 PROTOCOL
        ' APPLY ITS TRANSFORMATIONS FIRST
        If _Mount_X1010(filename, signature, certCode, reservedArea1, protocolVersion, hookSequence, data, data2, data3) Then Return True

        Select Case hookSequence
            Case MountSequence.DescriptorTableLineProcess ' Data2 is line Buffer
                If data2(0) = "obfuscationseed" Then
                    If data2.Length = 2 Then
                        _X1020_ObfuscationSeed = data2(1)
                        Return True
                    Else
                        _AddLog("Fatal: Cant read obfuscation seed from Descriptor Table. Malformed instruction.")
                        Throw New InvalidOperationException("Malformed obfuscation seed inside Descriptor Table")
                    End If
                Else
                    Return False
                End If
            Case MountSequence.MftTableRaw ' Decrypt and deobfuscate MFT table
                If (_packageEncryptionPassword Is Nothing) OrElse (_packageEncryptionPassword.Length < 4) Then
                    _AddLog("Error: Encryption password is too short. Aborted.")
                    Return True
                End If

                Try
                    ' Derive Encryption Key and Initialization Vector from passphrase and SALT
                    Dim key() As Byte
                    Dim vector() As Byte
                    Dim deriver As New System.Security.Cryptography.Rfc2898DeriveBytes(_packageEncryptionPassword, _MFT_ENCRYPTION_SALT, 2740)
                    Dim localbuffer() As Byte = data
                    key = deriver.GetBytes(32)
                    vector = deriver.GetBytes(16)
                    deriver = Nothing
                    Dim decryptor As New System.Security.Cryptography.RijndaelManaged()
                    decryptor.Key = key
                    decryptor.IV = vector
                    decryptor.BlockSize = 128
                    Dim decryptedMftStream As New System.IO.MemoryStream()
                    Dim cryptoS As New System.Security.Cryptography.CryptoStream(decryptedMftStream, decryptor.CreateDecryptor, Security.Cryptography.CryptoStreamMode.Write)
                    cryptoS.Write(localbuffer, 0, localbuffer.Length)
                    cryptoS.Close()
                    cryptoS.Dispose()
                    cryptoS = Nothing
                    decryptor = Nothing
                    localbuffer = decryptedMftStream.ToArray()
                    decryptedMftStream.Dispose()
                    decryptedMftStream = Nothing
                    Erase vector, key

                    ' Deobfuscate MFT if seed is available
                    If (_X1020_ObfuscationSeed IsNot Nothing) AndAlso (_X1020_ObfuscationSeed.Length > 0) Then
                        Dim i As Long
                        Dim i2 As Integer = 0
                        For i = 0 To localbuffer.Length - 1
                            If i2 >= _X1020_ObfuscationSeed.Length Then i2 = 0

                            localbuffer(i) = (localbuffer(i)) Xor (Val(_X1020_ObfuscationSeed(i2)))
                            i2 = i2 + 1
                        Next
                    Else
                        _AddLog("Warning: Skipping obfuscation since no seed is defined.")
                    End If

                    data = localbuffer
                    Return False ' Continue Mounting
                Catch ex As Exception
                    _AddLog("Fatal: Unhandled Exception while decrypting MFT table.")
                    Return True
                End Try
            Case Else
                Return False ' Continue Mounting
        End Select
    End Function

End Class
